package com.xdf.whiteaccount.service.impl;

import com.xdf.whiteaccount.dao.DyeFabricPlanMapper;
import com.xdf.whiteaccount.entity.DyeFabricPlan;
import com.xdf.whiteaccount.entity.GjrkbillCp;
import com.xdf.whiteaccount.service.BillCodeService;
import com.xdf.whiteaccount.service.GjrkbillCpService;
import com.xdf.whiteaccount.utils.BusinessException;
import com.xdf.whiteaccount.utils.Example;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.xdf.whiteaccount.entity.CpBillfh;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import com.xdf.whiteaccount.dao.CpBillfhMapper;
import com.xdf.whiteaccount.service.CpBillfhService;

/**
 * @Description : com.xdf.whiteaccount.service.impl(业务层实现类,该类为生成器自动生成).
 * @Author : 张柯
 * @Date : 2021-06-25 09:44:52
 */
@Service
public class CpBillfhServiceImpl implements CpBillfhService {
    @Autowired
    private CpBillfhMapper dao;
    @Autowired
    private GjrkbillCpService gjrkbillCpService;
    @Autowired
    private DyeFabricPlanMapper dyeFabricPlanMapper;
    @Lazy
    @Autowired
    private CpBillfhServiceImpl meService;
    @Autowired
    private BillCodeService billCodeService;

    public static final String BILL_CODE_FLAG = "色布发货";

    /**
     * @Describe 新增方法
     * @author 张柯
     * @Date 2021-06-25 09:44:52
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insert(CpBillfh record) throws Exception {
        return dao.insert(record);
    }

    /**
     * @Describe 选择新增
     * @author 张柯
     * @Date 2021-06-25 09:44:52
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertSelective(CpBillfh record) throws Exception {
        return dao.insertSelective(record);
    }

    /**
     * @Describe 批量新增
     * @author 张柯
     * @Date 2021-06-25 09:44:52
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int multiInsert(List<CpBillfh> list) throws Exception {
        return dao.multiInsert(list);
    }

    /**
     * @Describe 修改
     * @author 张柯
     * @Date 2021-06-25 09:44:52
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateByPrimaryKey(CpBillfh record) throws Exception {
        return dao.updateByPrimaryKey(record);
    }

    /**
     * @Describe 选择修改
     * @author 张柯
     * @Date 2021-06-25 09:44:52
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateByPrimaryKeySelective(CpBillfh record) throws Exception {
        return dao.updateByPrimaryKeySelective(record);
    }

    /**
     * @Describe 修改
     * @author 张柯
     * @Date 2021-06-25 09:44:52
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int update(CpBillfh record) throws Exception {
        return dao.updateByPrimaryKey(record);
    }

    /**
     * @Describe 批量修改
     * @author 张柯
     * @Date 2021-06-25 09:44:52
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int multiUpdate(List<CpBillfh> list) throws Exception {
        list.forEach(item -> dao.updateByPrimaryKeySelective(item));
        return list.size();
    }

    /**
     * @Describe 根据主键查询
     * @author 张柯
     * @Date 2021-06-25 09:44:52
     */
    @Override
    public CpBillfh selectByPrimaryKey(Integer id) throws Exception {
        return dao.selectByPrimaryKey(id);
    }

    /**
     * @Describe 根据主键删除
     * @author 张柯
     * @Date 2021-06-25 09:44:52
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteByPrimaryKey(Integer id) throws Exception {
        return dao.deleteByPrimaryKey(id);
    }

    /**
     * @Describe 根据Entity查询
     * @author 张柯
     * @Date 2021-06-25 09:44:52
     */
    @Override
    public List<CpBillfh> listQuery(CpBillfh record) throws Exception {
        return dao.selectByParam(record);
    }

    /**
     * 根据色布打卷入库主键数组统计后写入色布发货数据
     * @param jrkIdList
     * @return
     */
    @Override
    public List<CpBillfh> insert8JrkIdList(List<Integer> jrkIdList) throws Exception {
        List<CpBillfh> cpBillfhList = selectCollectionByKeyList(jrkIdList);
        if(cpBillfhList == null || cpBillfhList.size() == 0) return null;

        List<CpBillfh> ret = new ArrayList<>();
        for (CpBillfh item : cpBillfhList) {
            insertSelective(item);
            ret.add(item);
        }
        return ret;
    }

    @Override
    public List<CpBillfh> insert8JrkIdList(CpBillfh record, List<Integer> jrkIdList) throws Exception{
        // 根据打卷主键获取打卷明细数据时候要求两个字段：B_FPDID,B_upload 都是0
        // 即同时满足条件：没有发货，没有被其他设备扫码（正在发货）
        List<CpBillfh> cpBillfhList = selectCollectionByKeyList(jrkIdList);
        if(cpBillfhList == null || cpBillfhList.size() == 0) return null;

        List<DyeFabricPlan> dyeFabricPlanList = dyeFabricPlanMapper.selectByJrkCPIdList(jrkIdList);

        List<CpBillfh> ret = new ArrayList<>();
        for (CpBillfh item : cpBillfhList) {
            // 写入发货单属性
            String newBillCode = billCodeService.getNewBillCode(BILL_CODE_FLAG);
            item.setBillcode(newBillCode);

            String client = Optional.ofNullable(record.getClient()).orElse("");
            if(client.length() > 0)
                item.setClient(client);
            
            item.setCheckout(record.getCheckout());
            item.setMemo(record.getMemo());
            item.setManager(record.getManager());
            item.setCarnumber(record.getCarnumber());
            item.setPrintheader(record.getPrintheader());

            // 保存发货单明细数据并获取自增的主键
            meService.insertSelective(item);

            // 过滤符合当前发货：品名、规格、颜色的打卷计划数据（字段upload是打卷表主键）
            // 等待后面写入发货主键
            List<DyeFabricPlan> targetPlanList = dyeFabricPlanList.stream().filter(shelve ->
                    shelve.getProductName().equalsIgnoreCase(item.getProductName()) &&
                            shelve.getMaterialSpecification().equalsIgnoreCase(item.getSpecification()) &&
                            shelve.getColor().equalsIgnoreCase(item.getColor())
            ).collect(Collectors.toList());

            // 向打卷表字段 B_FPDID 写入发货主键
            if(targetPlanList.size() > 0)
                targetPlanList.forEach(plan -> {
                    GjrkbillCp gjrkbillCp = new GjrkbillCp();
                    gjrkbillCp.setBItemID(plan.getUpload());// plan.getUpload() = 成品打卷表主键 = g_jrkbill_cp.B_ItemID
                    gjrkbillCp.setBFPDID(item.getId());
                    gjrkbillCpService.updateByPrimaryKeySelective(gjrkbillCp);
                });

            ret.add(item);
        }

        return ret;
    }

    @Transactional
    @Override
    public List<CpBillfh> insert8ShelvesList(List<String> shelvesList) throws Exception{
        List<CpBillfh> cpBillfhList = meService.selectCollectionByShelvesList(shelvesList);
        if(cpBillfhList == null || cpBillfhList.size() == 0) return null;

        // 根据货架号查询获取对应的：货架号、品名、规格、颜色
        // 后面创建发货与打卷的关联外键数据时用到
        List<DyeFabricPlan> dyeFabricPlanList = dyeFabricPlanMapper.selectByShelvesList(shelvesList);

        List<CpBillfh> ret = new ArrayList<>();
        for (CpBillfh item : cpBillfhList) {
            meService.insertSelective(item);

            // 将发货明细主键回写入打卷明细表，建立两者的关联
            List<DyeFabricPlan> targetShelveList = dyeFabricPlanList.stream().filter(shelve ->
                    shelve.getProductName().equalsIgnoreCase(item.getProductName()) &&
                            shelve.getMaterialSpecification().equalsIgnoreCase(item.getSpecification()) &&
                            shelve.getColor().equalsIgnoreCase(item.getColor())
            ).collect(Collectors.toList());
            // 有相同：品名、规格、颜色的货架号，遍历其设置发货主键，属性 planCode 中保存的是货架号
            if(targetShelveList.size() > 0)
                targetShelveList.forEach(shelve -> dao.buildJrkRelation(item.getId(),shelve.getPlanCode()));

            ret.add(item);
        }
        return ret;
    }

    /**
     * 根据色布打卷主键查询并汇总返回色布发货数据集合
     * @param jrkIdList
     * @return
     */
    @Override
    public List<CpBillfh> selectCollectionByKeyList(List<Integer> jrkIdList){
        if(jrkIdList == null || jrkIdList.size() == 0) return null;
        return dao.selectCollectionByKeyList(jrkIdList);
    }

    @Override
    public List<CpBillfh> selectCollectionByShelvesList(List<String> shelvesList){
        if(shelvesList == null || shelvesList.size() == 0) return null;
        return dao.selectCollectionByShelvesList(shelvesList);
    }

    @Override
    public List<CpBillfh> insert8ShelvesList(CpBillfh record, List<String> shelvesList) throws Exception{
        List<CpBillfh> cpBillfhList = meService.selectCollectionByShelvesList(shelvesList);
        if(cpBillfhList == null || cpBillfhList.size() == 0) return null;

        // 根据货架号查询获取对应的：货架号、品名、规格、颜色
        // 后面创建发货与打卷的关联外键数据时用到
        List<DyeFabricPlan> dyeFabricPlanList = dyeFabricPlanMapper.selectByShelvesList(shelvesList);

        for (CpBillfh item : cpBillfhList) {
            String newBillCode = billCodeService.getNewBillCode(BILL_CODE_FLAG);
            item.setBillcode(newBillCode);

            // 有前端传入的客户则以前端为准
            String client = Optional.ofNullable(record.getClient()).orElse("");
            if(client.length() > 0)
                item.setClient(client);

            item.setCheckout(record.getCheckout());
            item.setMemo(record.getMemo());
            item.setManager(record.getManager());
            item.setCarnumber(record.getCarnumber());
            item.setPrintheader(record.getPrintheader());
            item.setAddress(record.getAddress());
        }

        List<CpBillfh> ret = new ArrayList<>();
        for (CpBillfh item : cpBillfhList) {
            meService.insertSelective(item);

            // 将发货明细主键回写入打卷明细表，建立两者的关联
            List<DyeFabricPlan> targetShelveList = dyeFabricPlanList.stream().filter(shelve ->
                    shelve.getProductName().equalsIgnoreCase(item.getProductName()) &&
                            shelve.getMaterialSpecification().equalsIgnoreCase(item.getSpecification()) &&
                            shelve.getColor().equalsIgnoreCase(item.getColor())
            ).collect(Collectors.toList());
            // 有相同：品名、规格、颜色的货架号，遍历其设置发货主键，属性 planCode 中保存的是货架号
            if(targetShelveList.size() > 0)
                targetShelveList.forEach(shelve -> dao.buildJrkRelation(item.getId(),shelve.getPlanCode()));

            ret.add(item);
        }
        return ret;
    }

    /**
     * 作废一个发货颜色汇总数据，要做如下关联清除：
     * 1. 作废发货单数据
     * 2. 清除成品打卷表字段 B_FPDID
     * 3. 清除成品打卷表字段 B_upload
     * 4. 清除成品打卷表字段 scan_id
     * @param id
     * @return
     */
    @Transactional
    @Override
    public int setVoid(Integer id){
        CpBillfh cpBillfh = dao.selectByPrimaryKey(id);
        if(cpBillfh == null) throw new BusinessException("没有找到该发货数据！");
        cpBillfh.setState(0);
        dao.updateByPrimaryKeySelective(cpBillfh);// 作废发货数据
        return gjrkbillCpService.clearFPDIDBatch(id);// 清除：发货主键、扫描设备编号、扫描流水号
    }
}